package com.gan.simple_init.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gan.simple_init.common.constant.ExcelConstant;
import com.gan.simple_init.mapper.MovieMapper;
import com.gan.simple_init.model.movie.dto.AddMovieDto;
import com.gan.simple_init.model.movie.entity.Movie;
import com.gan.simple_init.service.MovieService;
import com.gan.simple_init.util.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author gbw
 * @description 针对表【movie(电影)】的数据库操作Service实现
 * @createDate 2023-10-25 10:09:07
 */
@Service
public class MovieServiceImpl extends ServiceImpl<MovieMapper, Movie>
        implements MovieService {

    private static final Date BEGIN_DATE = DateUtil.parse("1800-01-01", "yyyy-mm-dd");
    private static final Date END_DATE = DateUtil.offset(DateUtil.date(), DateField.YEAR, 100);
    private static final char ZERO = '0';
    private static final Integer MAX_DURATION = 500;

    @Override
    public String validMovieInfo(Movie movie) {
        Date releaseDate = movie.getReleaseDate();
        String durationStr = movie.getDuration();
        String director = movie.getDirector();
        String title = movie.getTitle();

        // 导演和电影名称不能为空
        if (StringUtils.isAnyBlank(director,title)){
            return "导演和电影名称不能为空";
        }

        // 上映日期要在1800年-今天开始一百年内
        if (!ObjectUtils.isEmpty(releaseDate) && !DateUtil.isIn(releaseDate, BEGIN_DATE, END_DATE)) {
            return "上映日期要在 " + DateUtil.format(BEGIN_DATE, "yyyy-mm-dd") + " 到 "
                    + DateUtil.format(END_DATE, "yyyy-mm-dd") + " 之间!";
        }

        // 时长校验
        if (StringUtils.isNotBlank(durationStr)) {
            // 取出正确时长
            Integer duration = 0;
            for (int i = 0; i < durationStr.length(); i++) {
                char c = durationStr.charAt(i);
                if (i == 0) {
                    if (!Character.isDigit(c) || c == ZERO) {
                        return "时长填写错误!";
                    }
                }
                if (!Character.isDigit(c)) {
                    break;
                }
                duration = duration * 10 + (c - '0');
            }
            if (duration > MAX_DURATION) {
                return "时长必须小于500!";
            }
        }
        return null;
    }

    @Override
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        try {
            ExcelUtil.buildFile(response,"电影信息模板");
            EasyExcel.write(response.getOutputStream(), AddMovieDto.class)
                    .registerWriteHandler(ExcelUtil.buildFirstLine((short) 1400,ExcelConstant.Caution.MOVIE,10))
                    // 设置默认样式及写入头信息开始的行数
                    .relativeHeadRowIndex(1)
                    .sheet()
                    // 用自定义头的话EasyExcel的样式注解会失效
//                    .head(ExcelUtil.buildHead(ExcelConstant.ModelHeader.MOVIE))
                    .doWrite(new ArrayList<>());
        } catch (Exception e) {
            ExcelUtil.buildError(response,"电影信息模板下载失败");
        }
    }


    @Override
    public void downloadData(HttpServletResponse response) throws IOException {
        try {
            ExcelUtil.buildFile(response,"电影信息");
            EasyExcel.write(response.getOutputStream(), AddMovieDto.class)
                    .sheet()
                    .doWrite(getExcelData());
        } catch (Exception e) {
            ExcelUtil.buildError(response,"电影数据导出失败");
        }
    }

    /**
     * 获得Excel数据
     * @return
     */
    public List<AddMovieDto> getExcelData() {
        List<Movie> movieList = this.list();
        return movieList.stream().map(Movie::toAddMovieDto).collect(Collectors.toList());
    }
}




